package org.ucas.faker.web.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.ucas.faker.web.entity.Query;
import org.ucas.faker.web.service.QueryService;
import org.ucas.faker.web.service.similar.SimilarService;
import org.ucas.faker.web.utils.model.RawPatent;
import org.ucas.faker.web.dto.CarryDto;
import org.ucas.faker.web.dto.PageDto;
import org.ucas.faker.web.dto.ResponseDto;
import org.ucas.faker.web.entity.Depot;
import org.ucas.faker.web.entity.TaskLog;
import org.ucas.faker.web.entity.User;
import org.ucas.faker.web.exceptions.BadRequestException;
import org.ucas.faker.web.exceptions.InternalServerException;
import org.ucas.faker.web.utils.wx.WxPage;
import org.ucas.faker.web.utils.wx.WxTranslator;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
public class SearchController extends BaseController {

  @Autowired
  private WxTranslator translator;

  @Autowired
  private QueryService queryService;

  @Autowired
  private SimilarService similarService;
  
  @RequestMapping(value = "/search/senior.html", method = RequestMethod.GET)
  public ModelAndView senior() {
    ModelAndView view = new ModelAndView("/search/senior");
    view.addObject("user",currentUser());
    return view;
  }

  @RequestMapping(value = "/search/form.html",method = RequestMethod.GET)
  public ModelAndView form() {
    User user = currentUser();
    if(user == null) {
      user = userService.findByAccount("root");
      context().userId = user.getId();
    }
    ModelAndView view = new ModelAndView("/search/form");
    if(currentUserId() != null)
      view.addObject("user",user);

    return view;
  }
  @RequestMapping(value = "/search/similar.html",method = RequestMethod.GET)
  public ModelAndView similar() {
    User user = currentUser();
    if(user == null) {
      user = userService.findByAccount("root");
      context().userId = user.getId();
    }
    ModelAndView view = new ModelAndView("/search/similar");
    if(currentUserId() != null)
      view.addObject("user",user);

    return view;
  }
  @RequestMapping(value = "/search/legal.html",method = RequestMethod.GET)
  public ModelAndView legal() {
    User user = currentUser();
    if(user == null) {
      user = userService.findByAccount("root");
      context().userId = user.getId();
    }
    ModelAndView view = new ModelAndView("/search/legal");
    if(currentUserId() != null)
      view.addObject("user",user);

    return view;
  }
  @RequestMapping(value = "/patents/patentslist.html",method = RequestMethod.GET)
  public ModelAndView formShow() {
    User user = currentUser();
    if(user == null) {
      user = userService.findByAccount("root");
      context().userId = user.getId();
    }
    ModelAndView view = new ModelAndView("/patents/patentslist");
    if(currentUserId() != null)
      view.addObject("user",user);

    return view;
  }
  @RequestMapping(value = "/patents/graphpatentslist.html",method = RequestMethod.GET)
  public ModelAndView graphPatentsShow() {
    User user = currentUser();
    if(user == null) {
      user = userService.findByAccount("root");
      context().userId = user.getId();
    }
    ModelAndView view = new ModelAndView("/patents/graphpatentslist");
    if(currentUserId() != null)
      view.addObject("user",user);

    return view;
  }
  @RequestMapping(value = "/search/wx/access_token", method = RequestMethod.GET)
  @ResponseBody
  public ResponseDto getAccessToken() {
    if(wxClient.getAccessToken() == null) wxClient.authorize();

    return new ResponseDto(HttpStatus.OK, wxClient.getAccessToken());
  }

  private List<String> extractKeyWords(String query) {
    if (query == null || query.length() == 0) {
      return new ArrayList<>();
    } else {
      String[] t = query.split("\"");
      List<String> n = new ArrayList<>();
      for (int i = 0; i < t.length; i++) {
        if (i % 2 == 1) {
          n.add(t[i]);
        }
      }
      return n;
    }
  }
  @RequestMapping(value = "/search/similar", method = RequestMethod.POST)
  @ResponseBody
  public ResponseDto localSearch(@RequestParam(value = "query", required = true) String query){
	  similar_query(query);
	  return ResponseDto.OK;
  }
  
  @RequestMapping(value = "/similar/patents", method = RequestMethod.POST)
  @ResponseBody
  public PageDto<RawPatent> similarPatents(@RequestParam(value = "pageNumber", required = false) Integer pageNumber) throws InterruptedException{
	  String query = similar_query();
	  Long depotId = context().depotId;
	  List<RawPatent> patents = similarService.getSimilarPatentList(query, depotId);
	  System.out.println(patents.size());
	  return PageDto.ofList(patents, patents.size(), pageNumber, 20);
  }
  
  @RequestMapping(value = "/search/wx", method = RequestMethod.POST)
  @ResponseBody
  public PageDto<RawPatent> wxSearch(@RequestParam(value = "query", required = false) String query,
                                     @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
                                     @RequestParam(value = "fq", required = false) String fq,
                                     @RequestParam(value = "mp", required = false) String mp,
                                     @RequestParam(value = "ext", required = false) String ext,
                                     @RequestParam(value = "sort", required = false) String sort) {

    if(query != null) {
      keywords(extractKeyWords(query));
    }
    query = query == null? currentQuery() : query;

    String wxQuery = translator.translate(query);
    PageDto<RawPatent> patents = null;
    try {
    	//patents = wxClient.search(wxQuery,pageNumber);
      patents = wxClient.search(wxQuery,fq,pageNumber,mp,ext,sort);
    } catch (UnsupportedEncodingException e) {
      throw InternalServerException.WX_SERVICE_ERR;
    }
    if(patents == null) throw InternalServerException.WX_SERVICE_ERR;

    if(query != null && !query.equals(currentQuery())) {
      Query saved = new Query(currentUserId(),query,0);
      queryService.create(saved);
      context().query = query;
    }

    return patents;
  }
  @RequestMapping(value = "/search/get/query", method = RequestMethod.GET)
  @ResponseBody
  public CarryDto<String> getSearchQuery() {
    if (currentQuery() == null) {
      String n = "";
      return CarryDto.of(n);
    }
    return CarryDto.of(currentQuery());
  }

  @RequestMapping(value = "/search/analysis", method = RequestMethod.POST)
  @ResponseBody
  public ResponseDto searchAnalysis(@RequestParam(value = "yes_patents",required = false) List<String> include,@RequestParam(value = "not_patents",required = false) List<String> excluded, @RequestParam(value = "all_selected",required = false) int selected) {
	 if(include==null) include = new ArrayList<>();
	 if(excluded==null) excluded = new ArrayList<>();
	 System.out.println("include count:"+include.size()+"  "+"excluded count:"+excluded.size()+"  "+"selected:"+selected);
	 List<WxPage> pages;
	 if(selected == 1) {
		 pages = wxClient.sync(context().query,include,excluded);
	 }else {
		 pages = wxClient.sync(null,include,null);
	 }
	 Depot depot = depotService.create(currentUserId(), null);
	 depot.setDeleted(true);
	 depotService.persist(depot);
	 context().depotId = depot.getId();
	 
	 List<Long> patents = new ArrayList<>();
	 for(WxPage page : pages) {
		 patents.addAll(page.getSuccessed());
	 }
	 depotService.addPatents(depot.getId(),patents,1);
	 return ResponseDto.OK;
  }





  @RequestMapping(value = "/search/summary", method = RequestMethod.POST)
  CarryDto<Map> summary(@RequestParam(value = "count", defaultValue = "10",required = false) Integer cnt,
                          @RequestParam(value = "keys") List<String> keys) {
	
	String query = translator.translate(currentQuery());
	query = "ti = (电池)";
	String[] bb = keys.toArray(new String[keys.size()]);
	Map<String,List> res = wxClient.count(query,cnt,bb);
	

    return CarryDto.of(res);
  }
}
